use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{LazyLock, Mutex, OnceLock};
use std::thread;
use lazy_static::lazy_static;

//静态常量
const MAX_ID: usize =  usize::MAX / 2;
#[test]
fn test() {
    println!("用户ID允许的最大值是{}",MAX_ID);
}
//静态变量
// static mut REQUEST_RECV: usize = 0;
// fn test2() {
//     unsafe {
//         REQUEST_RECV += 1;
//         assert_eq!(REQUEST_RECV, 1);
//     }
// }
//和常量相同，定义静态变量的时候必须赋值为在编译期就可以计算出的值
//原子类型
static ATOMIC_COUNT: AtomicUsize  = AtomicUsize::new(0);
fn main() {
    for _ in 0..100 {
        ATOMIC_COUNT.fetch_add(1, Ordering::Relaxed);
    }

    println!("当前用户请求数{:?}",ATOMIC_COUNT);
}

struct Factory{
    factory_id: usize,
}

static GLOBAL_ID_COUNTER: AtomicUsize = AtomicUsize::new(0);
const MAX_ID_2: usize = usize::MAX / 2;
fn generate_id()->usize{
    // 检查两次溢出，否则直接加一可能导致溢出
    let current_val = GLOBAL_ID_COUNTER.load(Ordering::Relaxed);
    if current_val > MAX_ID_2{
        panic!("Factory ids overflowed");
    }
    GLOBAL_ID_COUNTER.fetch_add(1, Ordering::Relaxed);
    let next_id = GLOBAL_ID_COUNTER.load(Ordering::Relaxed);
    if next_id > MAX_ID{
        panic!("Factory ids overflowed");
    }
    next_id
}

impl Factory{
    fn new()->Self{
        Self{
            factory_id: generate_id()
        }
    }
}
//运行期初始化
lazy_static!{
    static ref NAMES: Mutex<String> = Mutex::new(String::from("Sunface, Jack, Allen"));
}

#[test]
fn test3() {
    let v = NAMES.lock().unwrap();
    println!("{}",v);
}
//当然，使用lazy_static在每次访问静态变量时，会有轻微的性能损失，
// 因为其内部实现用了一个底层的并发原语std::sync::Once，在每次访问该变量时，程
// 序都会执行一次原子指令用于确认静态变量的初始化是否完成

#[derive(Debug)]
struct Config {
    a: String,
    b: String,
}

// static mut CONFIG: Option<&mut Config> = None;
// #[test]
// fn test4() {
//     let c = Box::new(Config {
//         a: "A".to_string(),
//         b: "B".to_string(),
//     });
//
//     unsafe {
//         // 将`c`从内存中泄漏，变成`'static`生命周期
//         CONFIG = Some(Box::leak(c));
//         println!("{:?}", CONFIG);
//     }
// }

static mut CONFIG2: Option<&mut Config> = None;

fn init() -> Option<&'static mut Config> {
    let c = Box::new(Config {
        a: "A".to_string(),
        b: "B".to_string(),
    });
    Some(Box::leak(c))
}

fn test7() {
    // 子线程中调用
    let handle = thread::spawn(|| {
        let logger = Logger::global();
        logger.log("thread message".to_string());
    });

    // 主线程调用
    let logger = Logger::global();
    logger.log("some message".to_string());

    let logger2 = Logger::global();
    logger2.log("other message".to_string());

    handle.join().unwrap();
}

#[derive(Debug)]
struct Logger;

static LOGGER: OnceLock<Logger> = OnceLock::new();

impl Logger {
    fn global() -> &'static Logger {
        // 获取或初始化 Logger
        LOGGER.get_or_init(|| {
            println!("Logger is being created..."); // 初始化打印
            Logger
        })
    }

    fn log(&self, message: String) {
        println!("{}", message)
    }
}

// fn test5() {
//     unsafe {
//         CONFIG = init();
//
//         println!("{:?}", CONFIG)
//     }
// }

fn test8() {
    // 子线程中调用
    let handle = thread::spawn(|| {
        let logger = &LOGGER2;
        logger.log("thread message".to_string());
    });

    // 主线程调用
    let logger = &LOGGER2;
    logger.log("some message".to_string());

    let logger2 = &LOGGER2;
    logger2.log("other message".to_string());

    handle.join().unwrap();
}

#[derive(Debug)]
struct Logger2;

static LOGGER2: LazyLock<Logger> = LazyLock::new(Logger2::new);

impl Logger2 {
    fn new() -> Logger {
        println!("Logger is being created...");
        Logger
    }

    fn log(&self, message: String) {
        println!("{}", message)
    }
}